package log

import (
	"log/slog"
	"os"
	"path/filepath"
	"photowall/pkg/config"
	"sync"
)

func init() {
	GetDatabaseLogger().Info(`GetDatabaseLogger work normal`)
	GetMainLogger().Info(`GetMainLogger work normal`)
	GetRedisLogger().Info(`GetRedisLogger work  normal`)
}

type DimLightLoggers struct {
	DatebaseLogger *slog.Logger
	RedisLogger    *slog.Logger
	MainLogger     *slog.Logger
}

func SetMainRouterWorkMode(mode string) {

}

var (
	dataBaseSyncOnce sync.Once
	databaseLogger   *slog.Logger

	redisSyncOnce sync.Once
	redisLogger   *slog.Logger

	mainSyncOnce sync.Once
	mainLogger   *slog.Logger
)

// 实现单例模式的 databaseLogger
func GetDatabaseLogger() *slog.Logger {
	dataBaseSyncOnce.Do(func() {
		DimlightGlobalConfig := config.GetConfig()

		logPath := DimlightGlobalConfig.LogConfig.LogPath.DatabaseLogPath
		checkAndMakeDir(logPath)

		databaseLogFile, err := os.OpenFile(logPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
		if err != nil {
			slog.Error("database logger 初始化失败")
			panic(err)
		}

		databaseLogger = slog.New(slog.NewTextHandler(databaseLogFile, nil))
	})

	return databaseLogger
}

// 实现单例模式的 redisLogger
func GetRedisLogger() *slog.Logger {
	redisSyncOnce.Do(func() {
		DimlightGlobalConfig := config.GetConfig()

		logPath := DimlightGlobalConfig.LogConfig.LogPath.RedisLogPath
		checkAndMakeDir(logPath)

		redisLogFile, err := os.OpenFile(logPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
		if err != nil {
			slog.Error("database logger 初始化失败")
			panic(err)
		}

		redisLogger = slog.New(slog.NewTextHandler(redisLogFile, nil))
	})

	return redisLogger
}

// 实现单例模式的 mainLogger
func GetMainLogger() *slog.Logger {
	mainSyncOnce.Do(func() {
		DimlightGlobalConfig := config.GetConfig()

		logPath := DimlightGlobalConfig.LogConfig.LogPath.MainLogPath
		checkAndMakeDir(logPath)

		mainLogFile, err := os.OpenFile(logPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
		if err != nil {
			slog.Error("database logger 初始化失败")
			panic(err)
		}

		mainLogger = slog.New(slog.NewTextHandler(mainLogFile, nil))
	})

	return mainLogger
}

func checkAndMakeDir(logPath string) bool {
	if !filepath.IsAbs(logPath) {
		panic("filepath is no absolute path")
	}

	logdir, _ := filepath.Split(logPath)
	slog.Info(logdir)

	if pathStat, err := os.Stat(logdir); err != nil {
		panic(err)
	} else {
		if os.IsNotExist(err) {
			err := os.Mkdir(logdir, os.ModeDir)
			if err != nil {
				slog.Error("can not make dir for logger")
				panic(err)
			}

		} else if pathStat.IsDir() {
			return true

		} else if !pathStat.IsDir() {
			panic("the path is existed, can not make dir")
		}
	}

	return true
}
